import { createSignal, onMount, onCleanup, Show, createResource } from "solid-js";
import { invoke } from "@tauri-apps/api/core";
import { appWindow } from "@tauri-apps/api/window";
import { register, unregister } from "@tauri-apps/api/globalShortcut";
import "./AILauncher.css";

interface AppInfo {
  name: string;
  path: string;
  icon_path?: string;
}

export function AILauncher() {
  const [query, setQuery] = createSignal("");
  const [results, setResults] = createSignal<string[]>([]);
  const [loading, setLoading] = createSignal(false);
  const [selectedIndex, setSelectedIndex] = createSignal(0);
  const [installedApps, setInstalledApps] = createSignal<AppInfo[]>([]);
  const [showingApps, setShowingApps] = createSignal(false);

  // Fetch installed applications
  const fetchInstalledApps = async () => {
    try {
      const apps = await invoke<AppInfo[]>("get_installed_apps");
      setInstalledApps(apps);
      console.log(`Loaded ${apps.length} applications`);
      return apps;
    } catch (error) {
      console.error("Error fetching installed applications:", error);
      return [];
    }
  };

  // Register global shortcut to show/hide the launcher
  onMount(async () => {
    try {
      // Fetch installed applications on startup
      await fetchInstalledApps();

      // Focus the input when the window is shown
      await appWindow.show();
      await appWindow.setFocus();
      document.getElementById("command-input")?.focus();

      // Hide the window when it loses focus
      const unlisten = await appWindow.onFocusChanged(({ payload: focused }) => {
        if (!focused) {
          appWindow.hide();
        }
      });

      onCleanup(() => {
        unlisten();
      });
    } catch (error) {
      console.error("Error setting up shortcuts:", error);
    }
  });

  async function processQuery() {
    if (!query().trim()) {
      setShowingApps(true);
      // Show all installed apps when query is empty
      const appResults = installedApps().map(app => `Launch ${app.name}`);
      setResults(appResults.slice(0, 10)); // Limit to 10 results for better UX
      setSelectedIndex(0);
      return;
    }
    
    setLoading(true);
    try {
      const searchTerm = query().toLowerCase();
      
      // First, search in installed applications
      const matchingApps = installedApps()
        .filter(app => app.name.toLowerCase().includes(searchTerm))
        .map(app => `Launch ${app.name}`);
      
      if (matchingApps.length > 0) {
        setShowingApps(true);
        setResults(matchingApps.slice(0, 10)); // Limit to 10 results
      } else {
        setShowingApps(false);
        // If no matching apps, fall back to AI query
        const aiResults = await invoke<string[]>("process_ai_query", { query: query() });
        setResults(aiResults);
      }
      
      setSelectedIndex(0);
    } catch (error) {
      console.error("Error processing query:", error);
      setResults([
        "Error processing query",
        "Please try again"
      ]);
    } finally {
      setLoading(false);
    }
  }

  function handleKeyDown(e: KeyboardEvent) {
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setSelectedIndex(prev => (prev < results().length - 1 ? prev + 1 : prev));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setSelectedIndex(prev => (prev > 0 ? prev - 1 : 0));
    } else if (e.key === "Enter") {
      e.preventDefault();
      if (results().length > 0) {
        executeCommand(results()[selectedIndex()]);
      } else {
        processQuery();
      }
    } else if (e.key === "Escape") {
      e.preventDefault();
      appWindow.hide();
    }
  }

  async function executeCommand(command: string) {
    console.log("Executing command:", command);
    
    // Handle different commands
    if (command === "Open Settings") {
      await invoke("plugin:window|create", {
        label: "settings",
        url: "settings"
      });
      await appWindow.hide();
    } else if (command.startsWith("Search the web for")) {
      const searchTerm = command.replace("Search the web for ", "");
      await invoke("plugin:shell|open", { 
        path: `https://www.google.com/search?q=${encodeURIComponent(searchTerm)}` 
      });
      await appWindow.hide();
    } else if (command.startsWith("Launch ")) {
      const appName = command.replace("Launch ", "");
      const appToLaunch = installedApps().find(app => app.name === appName);
      
      if (appToLaunch) {
        console.log(`Launching application: ${appToLaunch.path}`);
        await invoke("plugin:shell|open", { path: appToLaunch.path });
        await appWindow.hide();
      }
    } else {
      // For demo purposes, just hide the window
      await appWindow.hide();
    }
  }

  return (
    <div class="launcher-container">
      <div class="command-palette">
        <div class="search-container">
          <input
            id="command-input"
            type="text"
            placeholder="Type to search applications or ask anything..."
            value={query()}
            onInput={(e) => {
              setQuery(e.currentTarget.value);
              processQuery();
            }}
            onKeyDown={handleKeyDown}
            onFocus={() => {
              if (!query().trim()) {
                processQuery(); // Show all apps when focused with empty query
              }
            }}
          />
          <button 
            onClick={processQuery}
            disabled={loading()}
          >
            {loading() ? "..." : "↵"}
          </button>
        </div>
        
        <Show when={results().length > 0}>
          <div class="results-container">
            <ul>
              {results().map((result, index) => (
                <li 
                  class={index === selectedIndex() ? "selected" : ""}
                  onClick={() => executeCommand(result)}
                >
                  {showingApps() && result.startsWith("Launch ") ? (
                    <div class="app-result">
                      <span class="app-icon">🖥️</span>
                      <span>{result}</span>
                    </div>
                  ) : (
                    <div class="command-result">
                      {result}
                    </div>
                  )}
                </li>
              ))}
            </ul>
          </div>
        </Show>
      </div>
    </div>
  );
} 